package dst.ass1.jpa.model.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.hibernate.annotations.Index;

import dst.ass1.jpa.listener.WorkerListener;
import dst.ass1.jpa.model.ITaskForce;
import dst.ass1.jpa.model.ITaskProcessing;
import dst.ass1.jpa.model.ITaskWorker;
import dst.ass1.jpa.validator.WorkUnitCapacity;

@NamedQueries({
	 //find all TaskWorkers from Vienna
	  @NamedQuery(
	    name="findWorkersInVienna",
	    query="select t from TaskWorker t join t.taskProcessings e "+
	    		"where t.location like 'AUT-VIE%'"
	  )
})
@Entity
@EntityListeners({WorkerListener.class})
public class TaskWorker implements ITaskWorker{

	private final static Logger LOGGER = Logger.getLogger(TaskWorker.class.getName());
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO )
	private Long id;
	
	@Size(min=5, max=25)  ///1.3.a. every worker has a name not shorter than 5 and no longer than 25 characters.
	@Column(unique = true)
	private String name;
	
	@WorkUnitCapacity(min = 4, max = 8) //1.3.b platform only uses workers, which have a specific amount of capacity.
	private Integer workUnitCapacity;
	
	@Pattern(regexp="[A-Z]{3}-[A-Z]{3}@\\d{4,}")  //1.3.a. for example "AUT-VIE@1040"
	private String location;
	
	@Past			//1.3.a. A worker has dates for joined and lastTraining, both have to be in the past.
	private Date joinedDate;
	
	@Past			//1.3.a. A worker has dates for joined and lastTraining, both have to be in the past.
	private Date lastTraining;
	
	@ManyToOne(targetEntity=TaskForce.class, fetch=FetchType.EAGER)
	private ITaskForce taskForce;
	
	@ManyToMany(targetEntity = TaskProcessing.class, fetch=FetchType.LAZY, mappedBy="taskWorkers")
	private List<ITaskProcessing> taskProcessings;

	public TaskWorker (){
		this.taskProcessings = new ArrayList<ITaskProcessing>();
	}
	
	@Override
	public Long getId() {
		return id;
	}
	
	@Override
	public void setId(Long id) {
		this.id=id;
	}
	
	@Override
	public String getName() {
		return name;
	}
	
	@Override
	public void setName(String name) {
		this.name=name;
	}
	
	@Override
	public Integer getWorkUnitCapacity() {
		return workUnitCapacity;
	}
	
	@Override
	public void setWorkUnitCapacity(Integer workUnits) {
		this.workUnitCapacity=workUnits;	
	}
	
	@Override
	public String getLocation() {
		return location;
	}
	
	@Override
	public void setLocation(String location) {
		this.location=location;
	}
	
	@Override
	public Date getJoinedDate() {
		return joinedDate;
	}
	
	@Override
	public void setJoinedDate(Date joined) {
		this.joinedDate=joined;
	}
	
	@Override
	public Date getLastTraining() {
		return lastTraining;
	}
	
	@Override
	public void setLastTraining(Date lastTraining) {
		this.lastTraining=lastTraining;
	}
	
	@Override
	public ITaskForce getTaskForce() {
		return taskForce;
	}
	
	@Override
	public void setTaskForce(ITaskForce taskForce) {
		this.taskForce=taskForce;
	}
	
	@Override
	public List<ITaskProcessing> getTaskProcessings() {
		return taskProcessings;
	}
	
	@Override
	public void setTaskProcessings(List<ITaskProcessing> processings) {
		this.taskProcessings=processings;
	}
	
	
	@Override
	public void addTaskProcessing(ITaskProcessing processing) {
		if(this.taskProcessings!=null){
			this.taskProcessings.add(processing);
		}
		else{
			LOGGER.info("TaskWorker.List<ITaskProcessing> was null");
		}
		
	}

}
